"""
边缘优化选择对话框（重构版）
"""

import tkinter as tk
from tkinter import ttk
import numpy as np
import threading
from typing import Optional, Callable, Dict

from ...utils import get_logger
from .edge_method_config import EdgeMethodConfig
from .edge_thumbnail_panel import EdgeThumbnailPanel
from .edge_preview_panel import EdgePreviewPanel


class EdgeOptimizationDialogRefactored:
    """边缘优化选择对话框（重构版）"""
    
    def __init__(
        self,
        parent: tk.Tk,
        image: np.ndarray,
        mask: np.ndarray,
        image_processor,
        on_select: Optional[Callable] = None
    ):
        """
        初始化对话框
        
        Args:
            parent: 父窗口
            image: 原始图片 (RGB)
            mask: 掩码
            image_processor: 图像处理器实例
            on_select: 选择回调函数 (selected_method: str, optimized_mask: np.ndarray)
        """
        self.parent = parent
        self.image = image
        self.mask = mask
        self.image_processor = image_processor
        self.on_select = on_select
        self.logger = get_logger(__name__)
        
        # 创建窗口
        self.window = tk.Toplevel(parent)
        self.window.title("边缘优化选择")
        self.window.geometry("1200x800")
        self.window.transient(parent)
        self.window.grab_set()
        
        # 获取优化方法配置
        self.optimization_methods = EdgeMethodConfig.get_methods()
        self.method_order = EdgeMethodConfig.get_method_order()
        
        # 预处理结果
        self.optimized_results: Dict[str, np.ndarray] = {}
        self.selected_method = None
        
        # 创建UI组件
        self.thumbnail_panel = None
        self.preview_panel = None
        
        # 创建UI
        self._create_ui()
        
        # 在后台生成预览
        self._generate_previews()
    
    def _create_ui(self):
        """创建用户界面"""
        # 标题
        self._create_header()
        
        # 缩略图面板
        thumbnail_container = ttk.Frame(self.window, padding=10)
        thumbnail_container.pack(fill=tk.X)
        
        self.thumbnail_panel = EdgeThumbnailPanel(
            thumbnail_container,
            self.optimization_methods,
            self.method_order,
            self._on_thumbnail_clicked
        )
        
        # 预览面板
        preview_container = ttk.Frame(self.window, padding=10)
        preview_container.pack(fill=tk.BOTH, expand=True)
        
        self.preview_panel = EdgePreviewPanel(
            preview_container,
            self._on_param_change
        )
        
        # 底部按钮
        self._create_bottom_buttons()
    
    def _create_header(self):
        """创建标题"""
        title_frame = ttk.Frame(self.window, padding=10)
        title_frame.pack(fill=tk.X)
        
        ttk.Label(
            title_frame,
            text="选择边缘优化方法",
            font=("Arial", 14, "bold")
        ).pack(side=tk.LEFT)
        
        ttk.Label(
            title_frame,
            text="点击缩略图查看完整预览，然后选择优化方法添加到裁剪库",
            font=("Arial", 10)
        ).pack(side=tk.LEFT, padx=20)
    
    def _create_bottom_buttons(self):
        """创建底部按钮"""
        button_frame = ttk.Frame(self.window, padding=10)
        button_frame.pack(fill=tk.X)
        
        # 左侧状态标签
        self.status_label = ttk.Label(
            button_frame,
            text="正在生成预览...",
            font=("Arial", 10)
        )
        self.status_label.pack(side=tk.LEFT, padx=10)
        
        # 右侧按钮
        ttk.Button(
            button_frame,
            text="取消",
            command=self._on_cancel,
            bootstyle="secondary",
            width=12
        ).pack(side=tk.RIGHT, padx=5)
        
        self.confirm_btn = ttk.Button(
            button_frame,
            text="确定选择",
            command=self._on_confirm,
            bootstyle="success",
            width=12,
            state=tk.DISABLED
        )
        self.confirm_btn.pack(side=tk.RIGHT, padx=5)
    
    def _generate_previews(self):
        """生成所有预览图"""
        def generate():
            try:
                for method_key, method_info in self.optimization_methods.items():
                    # 生成优化结果
                    if method_info["method"] is None:
                        optimized_mask = self.mask.copy()
                    else:
                        _, optimized_mask = self.image_processor.apply_edge_optimization(
                            self.image,
                            self.mask,
                            method_info["method"],
                            **method_info.get("params", {})
                        )
                    
                    self.optimized_results[method_key] = optimized_mask
                    
                    # 生成预览图
                    h, w = self.image.shape[:2]
                    preview_image = np.zeros((h, w, 4), dtype=np.uint8)
                    preview_image[optimized_mask, :3] = self.image[optimized_mask]
                    preview_image[optimized_mask, 3] = 255
                    
                    # 裁剪到内容边界
                    preview_image = self._crop_to_content(preview_image, optimized_mask)
                    
                    # 更新UI
                    self.window.after(0, lambda k=method_key, img=preview_image: 
                                     self.thumbnail_panel.update_thumbnail(k, img))
                
                # 所有预览生成完成
                self.window.after(0, self._on_previews_complete)
                
            except Exception as e:
                self.logger.error(f"生成预览失败: {e}", exc_info=True)
                self.window.after(0, lambda: self.status_label.config(text=f"生成预览失败: {e}"))
        
        threading.Thread(target=generate, daemon=True).start()
    
    def _on_thumbnail_clicked(self, method_key: str):
        """缩略图点击事件"""
        self.selected_method = method_key
        self.thumbnail_panel.select_method(method_key)
        
        method_info = self.optimization_methods[method_key]
        
        # 更新标题
        self.preview_panel.update_title(
            f"预览：{method_info['name']}",
            method_info['description']
        )
        
        # 显示/隐藏参数面板
        if method_info.get("adjustable", False):
            self.preview_panel.show_params_panel()
        else:
            self.preview_panel.hide_params_panel()
        
        # 显示预览
        self._show_full_preview(method_key)
        
        # 启用确认按钮
        self.confirm_btn.config(state=tk.NORMAL)
    
    def _on_param_change(self):
        """参数变化回调"""
        if self.selected_method == "custom_smooth_harden":
            params = self.preview_panel.get_params()
            
            # 重新计算优化结果
            _, optimized_mask = self.image_processor.apply_edge_optimization(
                self.image,
                self.mask,
                "custom_smooth_harden",
                **params
            )
            
            self.optimized_results[self.selected_method] = optimized_mask
            
            # 更新预览
            self._show_full_preview(self.selected_method)
    
    def _show_full_preview(self, method_key: str):
        """显示完整预览"""
        if method_key not in self.optimized_results:
            return
        
        optimized_mask = self.optimized_results[method_key]
        
        # 生成预览图
        h, w = self.image.shape[:2]
        preview_image = np.zeros((h, w, 4), dtype=np.uint8)
        preview_image[optimized_mask, :3] = self.image[optimized_mask]
        preview_image[optimized_mask, 3] = 255
        
        # 裁剪到内容边界
        preview_image = self._crop_to_content(preview_image, optimized_mask)
        
        # 显示
        self.preview_panel.display_image(preview_image)
    
    def _on_previews_complete(self):
        """所有预览生成完成"""
        self.status_label.config(text="✓ 预览生成完成，请选择优化方法")
    
    def _on_cancel(self):
        """取消按钮"""
        self.window.destroy()
    
    def _on_confirm(self):
        """确认按钮"""
        if self.selected_method is None:
            return
        
        optimized_mask = self.optimized_results[self.selected_method]
        
        if self.on_select:
            self.on_select(self.selected_method, optimized_mask)
        
        self.window.destroy()
    
    @staticmethod
    def _crop_to_content(image: np.ndarray, mask: np.ndarray, padding: int = 2) -> np.ndarray:
        """裁剪到内容边界"""
        rows = np.any(mask, axis=1)
        cols = np.any(mask, axis=0)
        
        if not np.any(rows) or not np.any(cols):
            return image
        
        y_min, y_max = np.where(rows)[0][[0, -1]]
        x_min, x_max = np.where(cols)[0][[0, -1]]
        
        h, w = image.shape[:2]
        y_min = max(0, y_min - padding)
        y_max = min(h, y_max + padding + 1)
        x_min = max(0, x_min - padding)
        x_max = min(w, x_max + padding + 1)
        
        return image[y_min:y_max, x_min:x_max]

